SSH 端口转发
1. 简介
SSH 除了登录服务器,还可以作为加密通信的中介,充当两台服务器之间的通信加密跳板,使得原本不加密的通信变成加密通信。
这个功能称为端口转发 port forwarding ,又称 SSH 隧道 SSH tunnel 。
端口转发有两个主要作用:
- 将不加密的数据放在 SSH 安全连接里面传输,使得原本不安全的网络服务增加了安全性,比如通过端口转发访问 Telnet、FTP 等明文服务,数据传输就都会加密。
- 作为数据通信的加密跳板,绕过网络防火墙。
端口转发有三种使用方法: 动态转发,本地转发,远程转发。
2. 动态转发
动态转发指本机与 SSH 服务器建立加密连接,本机上从某个端口流出的数据都被传送到服务器上,再被服务器转发到该去的地方。
本机与服务器的连接用 SOCKS5 协议。需要把初始数据包转成 SOCKS5 数据包,才能被 SSH 转发。
它的一个使用场景就是,访问所有外部网站,都通过 SSH 转发。
动态转发需要把本地端口绑定到 SSH 服务器 ( 跳板机 )。至于 SSH 服务器要去访问哪一个网站,完全是动态的,取决于原始通信,所以叫做动态转发。
ssh -D <local_port> <tunnel_host> -N
中 -D
表示动态转发, <local_port>
是本地端口, <tunnel_host>
是 SSH 服务器地址, -N
表示这个 SSH 连接只进行端口转发,不登录远程 Shell,不执行远程命令,只充当隧道。
动态转发开启后执行 curl -x socks5://localhost:<local_port> http://www.google.com
测试。命令中,curl 的 -x
参数指定代理服务器,即通过 SOCKS5 协议的本地端口,访问 http://www.example.com。
如果经常使用动态转发,可以将以下设置写入 SSH 客户端 ~/.ssh/config 用户个人配置文件。
DynamicForward tunnel_host:local_port
3. 本地转发
本地转发指 SSH 服务器作为跳板机,建立本地计算机与目标机器间的加密连接。是点对点的转发。
直接转发初始数据包。
ssh -L [<local_host>:]<local_port>:<target_host>:<target_port> <tunnel_host> -f
中 -L
参数表示本地转发,所有发向本地主机 <local_host>
上的端口 <local_port>
的请求,都会转发到 SSH 跳板机 <tunnel_host>
,然后 SSH 跳板机作为中介,将收到的请求发到目标服务器 <target_host>
的目标端口 <target_port>
。 -f
参数表示这个转发在后台运行。
比如,现在有一台 SSH 跳板机 192.168.1.89
,要通过这台机器,在本地 2121
端口与目标机器 www.example.com
的 80
端口之间建立 SSH 隧道,就可以写成下面这样。
ssh -L 2121:www.example.com:80 192.168.1.89 -N
执行 curl http://localhost:2121
测试。
如果经常使用本地转发,可以将设置写入 SSH 客户端的用户个人配置文件 ~/.ssh/config。
Host test.example.com LocalForward client-IP:client-port server-IP:server-port
4. 远程转发
远程端口指的是在远程 SSH 服务器建立的转发规则。
直接转发初始数据包。
这种场景比较特殊,主要针对内网的情况。现有 本地计算机 A, 跳板机 B, 目标机 C:
- 本地计算机 A 在外网;
- SSH 跳板机 B 和目标服务器 C 都在内网;
- 本地计算机 A 无法访问内网之中的 SSH 跳板机 B;
- SSH 跳板机 B 可以访问本地计算机 A。
由于 A 无法访问内网 SSH 跳板机 B,就无法从外网建立 SSH 隧道。
必须反过来,从 SSH 跳板机 B 发起到 A 的隧道,建立端口转发,这时就形成了远程端口转发。
在 SSH 跳板机 B 执行 ssh -R <port_a>:<ip_c>:<port_c> -N <user_a>@<ip_a>
,意思是让 A 监听自己的 <port_a>
端口,并且数据由 <port_a>
流到 B 以后再经由 B 将数据包转发到 C 的 <port_c>
端口。 -R
参数表示远程端口转发。
那么用户就可以在 A 上执行 ssh -p <port_a> <user_a>@localhost
来连接到目标服务器 C。
显然,远程端口转发要求本地计算机 A 也安装了 SSH 服务器,这样才能接受 SSH 跳板机的远程登录。
如果经常执行远程端口转发,可以将设置写入 SSH 客户端的用户个人配置文件 ~/.ssh/config。
Host test.example.com RemoteForward local-IP:local_port target_ip:target_port
注意,需要打开 /etc/ssh/sshd_config 里的 AllowTcpForwarding
选项,否则不能进行远程转发。